package com.ccsoft.netty.chatroom;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.concurrent.GlobalEventExecutor;

/**
 * @author chanchaw
 * @create 2022-07-18 14:30
 */
public class ServerHandler extends SimpleChannelInboundHandler<String> {
    // GlobalEventExecutor.INSTANCE 是单例对象
    // 所有客户端 channel 都会加入该 channelGroup，之后广播消息用
    private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);

    // 客户端建立连接后第一个被触发的事件
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        channelGroup.add(channel);
        String msg = "[" + channel.remoteAddress() + "]加入聊天室...";
        // 无条件广播给所有客户端
//        channelGroup.writeAndFlush(msg);
        // 遍历，广播过程中给 排除客户端自己
        broadcastOthers(ctx,msg);
    }

    // 用户上线提醒
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
//        channelGroup.writeAndFlush("[" + channel.remoteAddress() + "]上线了~~~");
        System.out.println(channel.remoteAddress()+"上线了");
        broadcastOthers(ctx,"[" + channel.remoteAddress() + "]上线了~~~");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
//        channelGroup.writeAndFlush("[" + channel.remoteAddress() + "]下线了~~~");
        System.out.println(channel.remoteAddress()+"下线了");
        broadcastOthers(ctx,"[" + channel.remoteAddress() + "]下线了~~~");
    }

    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
//        channelGroup.writeAndFlush("[" + channel.remoteAddress() + "]退出了聊天室...");
        broadcastOthers(ctx,"[" + channel.remoteAddress() + "]退出了聊天室...");
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
        Channel channel = ctx.channel();
        broadcastOthers(ctx,"[" + channel.remoteAddress() + "]说：" + s);
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }

    // 广播给其他所有客户端
    private void broadcastOthers(ChannelHandlerContext ctx,String msg){
        Channel channel = ctx.channel();
        channelGroup.forEach(ch->{
            if(channel != ch)
                ch.writeAndFlush(msg);
        });
    }
}
